package com.fire.component.oss;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyun.oss.model.PutObjectResult;
import com.fire.component.dto.SingleResponse;
import com.fire.component.extension.ExceptionFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * OssOperate
 *
 * @author zwd
 * @date 2021/7/17
 */
@Slf4j
public class OssOperate {
    private OSSClient ossClient;
    private OssProperties ossProperties;
    public OssOperate(OSSClient ossClient, OssProperties ossProperties){
        Assert.notNull(ossClient, "ossClient should not null");
        Assert.notNull(ossProperties, "ossProperties should not be null");
        this.ossClient = ossClient;
        this.ossProperties = ossProperties;
    }

    public void uploadFileByFileStream(InputStream inputStream, String dirPrefix, String fileName) {
        Assert.notNull(inputStream, "inputStream should not be null");
        try {
            String bucketName = ossProperties.getBucketName();
            Assert.notNull(bucketName, "bucketName should not be null");
            ossClient.putObject(bucketName, dirPrefix + "/" + fileName, inputStream);
        }catch (Exception e) {
            log.error("文件上传oss失败");
            throw ExceptionFactory.ossException("文件上传oss失败");
        }finally {
            ossClient.shutdown();
        }
    }

    public SingleResponse<Map<String, String>> getUploadToken(){
        //https://zwd-store.oss-cn-hangzhou.aliyuncs.com/test.jpg
        String bucketName = ossProperties.getBucketName();
        String endpoint = ossProperties.getEndpoint();
        String accessId = ossProperties.getAccessKeyId();
        Assert.notNull(bucketName, "bucketName should not null");
        Assert.notNull(endpoint, "endpoint should not null");
        Assert.notNull(accessId, "accessId should not null");
        String host = "https://" + bucketName + "." + endpoint; // host的格式为 bucketname.endpoint
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir =format +  "/"; // 用户上传文件时指定的前缀。
        // 创建OSSClient实例。
        Map<String, String> respMap = null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB，即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            // respMap.put("expire", formatISO8601Date(expiration));

        } catch (Exception e) {
            log.error(e.getMessage());
            throw ExceptionFactory.ossException(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return SingleResponse.of(respMap);
    }
}
